package cn.iocoder.yudao.module.product.controller.app.spu;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.currency.api.rate.ExchangeRateApi;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.product.controller.app.spu.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.property.PropertyValueTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.IESimSpuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import cn.iocoder.yudao.module.promotion.api.combination.CombinationActivityApi;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationProductDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationSkuPriceDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;

@Tag(name = "用户 APP - 商品 SPU")
@RestController
@RequestMapping("/product/spu")
@Validated
@Slf4j
public class AppProductSpuController {

    @Resource
    private ProductSpuService productSpuService;
    @Resource
    private ProductSkuService productSkuService;
    @Resource
    private ProductBrowseHistoryService productBrowseHistoryService;

    @Resource
    private MemberLevelApi memberLevelApi;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private ProductPropertyValueService productPropertyValueService;
    @Resource
    private ExchangeRateApi exchangeRateApi;
    @Resource
    private IESimSpuService eSimSpuService;
    @Resource
    private CombinationActivityApi combinationActivityApi;

    @GetMapping("/list-by-ids")
    @Operation(summary = "获得商品 SPU 列表")
    @Parameter(name = "ids", description = "编号列表", required = true)
    public CommonResult<List<AppProductSpuRespVO>> getSpuList(@RequestParam("ids") Set<Long> ids) {
        List<ProductSpuDO> list = productSpuService.getSpuList(ids);
        if (CollUtil.isEmpty(list)) {
            return success(Collections.emptyList());
        }

        // 拼接返回
        list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
        List<AppProductSpuRespVO> voList = BeanUtils.toBean(list, AppProductSpuRespVO.class);

        // 处理 vip 价格
//        MemberLevelRespDTO memberLevel = getMemberLevel();
//        voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));

        // 设置spu支付价格
//        voList.forEach(vo -> setSpuPaymentPrice(vo));
        productSpuService.setAppDenominationVO(voList);

        return success(voList);
    }

    @RequestMapping(value = "/page", method = {RequestMethod.POST})
    @Operation(summary = "获得商品 SPU 分页")
    public CommonResult<PageResult<AppProductSpuRespVO>> getSpuPage(@Valid @RequestBody AppProductSpuPageReqVO pageVO) {
        PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty(pageResult.getTotal()));
        }

        return returnPageResult(pageResult);
    }

    @RequestMapping(value = "/search-by-name", method = {RequestMethod.POST})
    @Operation(summary = "按照商品名称搜索商品")
    public CommonResult<PageResult<AppProductSpuRespVO>> searchByName(@Valid @RequestBody AppProductSpuPageLikeNameReqVO reqVO) {
        PageResult<ProductSpuDO> pageResult = productSpuService.selectPageByLikeName(reqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty(pageResult.getTotal()));
        }

        return returnPageResult(pageResult);
    }

    private CommonResult<PageResult<AppProductSpuRespVO>> returnPageResult(PageResult<ProductSpuDO> pageResult) {
        // 拼接返回
        pageResult.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
        PageResult<AppProductSpuRespVO> voPageResult = BeanUtils.toBean(pageResult, AppProductSpuRespVO.class);

        productSpuService.setAppDenominationVO(voPageResult.getList());

        // 处理 vip 价格
//        MemberLevelRespDTO memberLevel = getMemberLevel();
//        voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));

//        // 团购价格
//        final List<Long> spuIds = voPageResult.getList().stream().map(AppProductSpuRespVO::getId).collect(Collectors.toList());
//        final List<CombinationSkuPriceDTO> combinationSkuList = combinationActivityApi.selectMinPriceSkuListBySpuId(spuIds);
//        if (CollUtil.isNotEmpty(combinationSkuList)) {
//            //combinationSkuList转换为map，key为skuId
//            final Map<Long, CombinationSkuPriceDTO> combinationSpuMap = combinationSkuList.stream()
//                    .collect(Collectors.toMap(CombinationSkuPriceDTO::getSpuId, Function.identity()));
//            voPageResult.getList().forEach(vo -> {
//                final CombinationSkuPriceDTO combinationSkuPriceDTO = combinationSpuMap.get(vo.getId());
//                if (combinationSkuPriceDTO != null) {
//                    // 有团购
//                    log.info("有团购, spuId = {}, combinationSkuPriceDTO = {}", vo.getId(), JsonUtils.toJsonString(combinationSkuPriceDTO));
//
//                    // 设置团购价格
//                    final Integer paymentCombinationPrice = exchangeRateApi.calculateWithCurrency(
//                            combinationSkuPriceDTO.getCombinationPrice(), vo.getCurrencyCode());
//                    vo.setPaymentCombinationPrice(paymentCombinationPrice);
//
//                    // 设置sku价格
//                    vo.setPrice(combinationSkuPriceDTO.getSkuPrice());
//
//                    // 设置折扣率
//                    final BigDecimal combinationDiscountRAppProductSpuControllerate = new BigDecimal(combinationSkuPriceDTO.getCombinationPrice())
//                            .divide(new BigDecimal(combinationSkuPriceDTO.getSkuPrice()), 2, BigDecimal.ROUND_HALF_UP);
//                    vo.setCombinationDiscountRate(combinationDiscountRate.toPlainString());
//                }
//            });
//        }
//
//        // 设置spu支付价格
//        voPageResult.getList().forEach(vo -> setSpuPaymentPrice(vo));

        return success(voPageResult);
    }

    @GetMapping("/get-detail")
    @Operation(summary = "获得商品 SPU 明细")
    @Parameter(name = "id", description = "SPU编号", required = true)
    @Parameter(name = "skuIds", description = "SKU编号")
    public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id,
                                                                @RequestParam(value = "skuIds", required = false) Set<Long> skuIds) {
        // 获得商品 SPU
        ProductSpuDO spu = productSpuService.getSpu(id);
        if (spu == null) {
            throw exception(SPU_NOT_EXISTS);
        }
        if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
            throw exception(SPU_NOT_ENABLE);
        }
        // 获得商品 SKU
        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId(), skuIds);

        // 增加浏览量
        //productSpuService.updateBrowseCount(id, 1);
        // 保存浏览记录
        //productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id);

        // 拼接返回
        spu.setBrowseCount(spu.getBrowseCount() + spu.getVirtualSalesCount());
        AppProductSpuDetailRespVO spuVO = BeanUtils.toBean(spu, AppProductSpuDetailRespVO.class)
                .setSkus(BeanUtils.toBean(skus, AppProductSpuDetailRespVO.Sku.class));

        // 处理 vip 价格
        //MemberLevelRespDTO memberLevel = getMemberLevel();
        //spuVO.setVipPrice(calculateVipPrice(spuVO.getPrice(), memberLevel));

        // 查询SPU基础属性
        final List<ProductPropertyValueDetailRespDTO> spuProperty = productPropertyValueService.getSpuProperty(PropertyValueTypeEnum.SPU, id);
        if (CollUtil.isNotEmpty(spuProperty)) {
            final List<AppProductPropertyValueDetailRespVO> properties = spuProperty.stream().map(v -> BeanUtils.toBean(v,
                    AppProductPropertyValueDetailRespVO.class)).collect(Collectors.toList());
            spuVO.setProperties(properties);
        }

        // 设置sku支付价格
        setSkuPaymentPrice(spu, spuVO);

        // 设置spu支付价格
        //setSpuPaymentPrice(spu, spuVO);
        productSpuService.setAppDenominationVO(Arrays.asList(spuVO));

        return success(spuVO);
    }

//    // 设置spu支付价格
//    private void setSpuPaymentPrice(AppProductSpuRespVO spuVO) {
//        final String spuCurrencyCode = spuVO.getCurrencyCode();
//
//        // 结算货币
//        final String paymentCurrency = exchangeRateApi.getPaymentCurrency();
//        spuVO.setPaymentCurrency(paymentCurrency);
//
//        // 结算sku价格
//        final Integer paymentPrice = exchangeRateApi.calculateWithCurrency(spuVO.getPrice(), spuCurrencyCode);
//        spuVO.setPaymentPrice(paymentPrice);
//    }
//
//
//    // 设置spu支付价格
//    private void setSpuPaymentPrice(ProductSpuDO spu, AppProductSpuDetailRespVO spuVO) {
//        final String spuCurrencyCode = spu.getCurrencyCode();
//
//        // 结算货币
//        final String paymentCurrency = exchangeRateApi.getPaymentCurrency();
//        spuVO.setPaymentCurrency(paymentCurrency);
//
//        // 结算价格
//        //final Integer paymentPrice = exchangeRateApi.calculateWithCurrency(spu.getPrice(), spuCurrencyCode);
//        //spuVO.setPaymentPrice(paymentPrice);
//    }

    // 设置sku支付价格
    private void setSkuPaymentPrice(ProductSpuDO spu, AppProductSpuDetailRespVO spuVO) {
        final List<CombinationProductDTO> combinationProducts = combinationActivityApi.getCombinationProductBySpuIdV2(spu.getId());

        final Map<Long, CombinationProductDTO> combinationSkuMap = combinationProducts.stream()
                .collect(Collectors.toMap(CombinationProductDTO::getSkuId, v -> v, (existing, replacement) -> existing));

        final String spuCurrencyCode = spu.getCurrencyCode();
        if (CollUtil.isNotEmpty(spuVO.getSkus())) {
            for (AppProductSpuDetailRespVO.Sku sku : spuVO.getSkus()) {
                // 结算货币
                final String paymentCurrency = exchangeRateApi.getPaymentCurrency();
                sku.setPaymentCurrency(paymentCurrency);

                // 结算价格
                final Integer paymentPrice = exchangeRateApi.calculateWithCurrency(sku.getPrice(), spuCurrencyCode);
                sku.setPaymentPrice(paymentPrice);

                // 普通折扣
                sku.setDiscountRateExcludeCombination(new BigDecimal(sku.getDiscountRate()).stripTrailingZeros().toPlainString());

                // 团购折扣
                final CombinationProductDTO combinationProduct = combinationSkuMap.get(sku.getId());
                log.info("查询sku的团购, skuId = {}, combinationProduct = {}", sku.getId(), combinationProduct);
                if (combinationProduct != null) {
                    final BigDecimal discountRate;
                    if (sku.getCustomDenomination()) {
                        discountRate = new BigDecimal(combinationProduct.getCombinationPrice())
                                .divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP)
                                .multiply(new BigDecimal(100));
                    } else {
                        discountRate = new BigDecimal(combinationProduct.getCombinationPrice())
                                .divide(new BigDecimal(sku.getDenominationFixed()), 2, BigDecimal.ROUND_HALF_UP)
                                .multiply(new BigDecimal(100));
                    }
                    sku.setDiscountRate(discountRate.stripTrailingZeros().toPlainString());
                } else {
                    sku.setDiscountRate(new BigDecimal(sku.getDiscountRate()).stripTrailingZeros().toPlainString());
                }

                // 设置面值最小、最大价格
                if (!sku.getCustomDenomination()) {
                    // 固定面值
                    // 面值定义价格
                    sku.setMinDenominationCardPrice(sku.getPrice());
                    sku.setMaxDenominationCardPrice(sku.getPrice());
                } else {
                    // 自定义面值
                    // 面值定义价格
                    sku.setMinDenominationCardPrice((sku.getMinCustomDenomination() / 100) * sku.getPrice());
                    sku.setMaxDenominationCardPrice((sku.getMaxCustomDenomination() / 100) * sku.getPrice());
                }

                // 面值支付价格
                sku.setMinDenominationPaymentPrice(exchangeRateApi.calculateWithCurrency(sku.getMinDenominationCardPrice(), spu.getCurrencyCode()));
                sku.setMaxDenominationPaymentPrice(exchangeRateApi.calculateWithCurrency(sku.getMaxDenominationCardPrice(), spu.getCurrencyCode()));
            }
        }
    }

    private MemberLevelRespDTO getMemberLevel() {
        Long userId = getLoginUserId();
        if (userId == null) {
            return null;
        }
        MemberUserRespDTO user = memberUserApi.getUser(userId);
        if (user.getLevelId() == null || user.getLevelId() <= 0) {
            return null;
        }
        return memberLevelApi.getMemberLevel(user.getLevelId());
    }

    /**
     * 计算会员 VIP 优惠价格
     *
     * @param price       原价
     * @param memberLevel 会员等级
     * @return 优惠价格
     */
    public Integer calculateVipPrice(Integer price, MemberLevelRespDTO memberLevel) {
        if (price == null || memberLevel == null || memberLevel.getDiscountPercent() == null) {
            return 0;
        }
        Integer newPrice = price * memberLevel.getDiscountPercent() / 100;
        return price - newPrice;
    }

    // TODO 芋艿：商品的浏览记录；

    // ========== 新增 =========


}
